package com.ztjava.core;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.template.Engine;
import com.jfinal.template.source.ClassPathSourceFactory;
import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.io.FileUtil;
import com.xiaoleilu.hutool.io.resource.ResourceUtil;
import com.xiaoleilu.hutool.util.CharsetUtil;
import com.ztjava.core.base.BaseSub;
import com.ztjava.core.bean.Database;
import com.ztjava.core.bean.SubBean;
import com.ztjava.core.interceptor.CoreInterceptor;
import com.ztjava.core.tool.ConfigTool;
import com.ztjava.core.tool.ScanTool;
import com.ztjava.core.tool.ViewTool;
import com.ztjava.core.utiliy.PathUtil;

public class Jsub extends JFinalConfig {
	private static Logger logger = Logger.getLogger(Jsub.class);
	
	public static boolean core_interceptor_custom = false; //是否自定义核心Interceptor
	
	public static boolean single_app = true;//默认单应用模式：每次启动清空event;每次启动清空权限

	public static boolean dev = true; // 是否开发模式
	public static boolean yun = false; // 是否是云系统
	public static String folder = null; // 应用文件夹
	public static String path = ""; // 主应用路径
	public static String res_path = ""; // 子应用路径
	public static String upload_path = "";//本地上传路径
	public static String upload_folder = "";//本地上传文件夹

	private String root_view_name = "view";// 模板根路径
	private JSONObject app_config;
	public static String app_config_name = "app_config.json";

	private JSONObject server_config;
	public static String server_config_name = ".json";

	private ScanTool scanTool = new ScanTool();
	private ConfigTool configTool = new ConfigTool();
	private Map<String, SubBean> subMap = new HashMap<String, SubBean>();
	private Map<String, BaseSub> objectMap = new HashMap<String, BaseSub>();

	public Jsub() {
		wellcome();
		// 应用配置
		app_config = JSONObject.parseObject(ResourceUtil.readUtf8Str(app_config_name));
		folder = PathUtil.getAppFolder();
		// 服务器配置覆盖
		server_config_name = folder + server_config_name;
		try {
			server_config = JSONObject.parseObject(FileUtil.readString(PathUtil.getWebPath()+File.separator+server_config_name, CharsetUtil.UTF_8));
			logger.warn(server_config.toJSONString());
		}catch (Exception e){
			logger.warn("未配置服务器端配置:"+server_config_name+"！");
		}
		
		// 解析常量
		configTool.parseConstant(app_config, server_config);
		// 解析子系统
		scanTool.scanSub(app_config, subMap, objectMap);
	}

	public void configConstant(Constants me) {
		logger.warn(DateUtil.now()+"Jsub启动configConstant");
		me.setDevMode(dev);
		me.setBaseUploadPath(Jsub.upload_path);

		// 子系统运行configConstant
		for (String key : objectMap.keySet()) {
			objectMap.get(key).configConstant(me);
		}
	}

	public void configRoute(Routes me) {
		logger.warn(DateUtil.now()+"Jsub启动configRoute");
		// 扫描Controller
		scanTool.scanController(me, subMap, app_config);

		// 子系统运行configRoute
		for (String key : objectMap.keySet()) {
			objectMap.get(key).configRoute(me);
		}
	}

	public void configEngine(Engine me) {
		logger.warn(DateUtil.now()+"Jsub启动configEngine");
		me.setDevMode(dev);
		// 模板文件来源自classPath
		me.setSourceFactory(new ClassPathSourceFactory());
		me.setBaseTemplatePath(root_view_name);
		// 共享项目根路径
		me.addSharedObject("path", path);
		me.addSharedObject("res_path", res_path);

		// 共享方法
		me.addSharedMethod(ViewTool.class);
		// 加载模板layout方法
		me.addSharedFunction("layout/hplus.html", 
				"layout/uikit.html",
				"layout/weui.html",
				"layout/layui.html");

		// 子系统运行configEngine
		for (String key : objectMap.keySet()) {
			objectMap.get(key).configEngine(me);
		}
	}

	public void configPlugin(Plugins me) {
		logger.warn(DateUtil.now()+"Jsub启动configPlugin");
		// 解析数据源
		Map<String, Database> dbMap = configTool.parseDb(me, app_config,server_config);
		// 扫描Model
		scanTool.scanModel(me, subMap, dbMap);
		// 配置Redis
		configTool.parseRedis(me, app_config, server_config);
		// 配置Weixin
		configTool.parseWeixin(me, app_config, server_config);
		// 事件插件
		configTool.parseEvent(me, app_config, server_config);

		// 子系统运行configPlugin
		for (String key : objectMap.keySet()) {
			objectMap.get(key).configPlugin(me);
		}
	}

	public void configInterceptor(Interceptors me) {
		logger.warn(DateUtil.now()+"Jsub启动configInterceptor");
		// 验证
		me.add(new CoreInterceptor());

		// 子系统运行configInterceptor
		for (String key : objectMap.keySet()) {
			objectMap.get(key).configInterceptor(me);
		}
	}

	public void configHandler(Handlers me) {
		logger.warn(DateUtil.now()+"Jsub启动configHandler");
		// 子系统运行configHandler
		for (String key : objectMap.keySet()) {
			objectMap.get(key).configHandler(me);
		}
	}

	public void afterJFinalStart() {
		logger.warn(DateUtil.now()+"Jsub启动afterJFinalStart");
		//子系统运行afterJFinalStart
		for (String key : objectMap.keySet()) {
			objectMap.get(key).afterJFinalStart();
		}
		configTool.parseAllConfig(app_config, server_config);
		//检查参数等等
		for (String key : objectMap.keySet()) {
			objectMap.get(key).startComplete();
		}

		logger.warn(DateUtil.now()+Jsub.folder+"启动完成");
		if(Jsub.single_app){
			logger.warn("单应用模式");
		}
		logger.warn(DateUtil.now()+"是否开发模式："+Jsub.dev);
	}

	private void wellcome() {
		logger.info("");
		logger.info("");
		logger.info("");
		logger.info("------------------");
		logger.warn(DateUtil.now()+"Jsub服务启动");
		logger.info("------------------");
		logger.info("感谢使用Jsub！");
		logger.info("------------------");
	}
}
